﻿using psafth.AMB;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace psafth.P3DecoderV2
{
    class Commands
    {
        private const byte DEFAULT_VERSION = 0x02;

        public static byte[] GetTime()
        {
            DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            TimeSpan epoch = DateTime.Now.Subtract(start);

            byte[] time = BitConverter.GetBytes(Convert.ToUInt64(epoch.TotalMilliseconds * 1000));

            List<byte> bytes = new List<byte>();
            bytes.Add(Convert.ToByte(AMBMessage.SOR));                  // Start Of Record
            bytes.Add(DEFAULT_VERSION);                                 // Version
            bytes.Add(0x00);                                            //
            bytes.Add(0x00);                                            // 
            bytes.Add(0x00);                                            // CRC LSB
            bytes.Add(0x00);                                            // CRC MSB
            bytes.Add(0x00);
            bytes.Add(0x00);
            bytes.Add(Convert.ToByte(AMBMessageType.GET_TIME));         // Type Of Record
            bytes.Add(0x00);

            /* Field of records */
            bytes.Add(Convert.ToByte(AMBGetTimeFOR.RTC_TIME));
            bytes.Add(Convert.ToByte(time.Length));
            bytes.AddRange(time);

            // End of record
            bytes.Add(Convert.ToByte(AMBMessage.EOR));

            byte[] tmpBytes = bytes.ToArray();

            // Calculate and insert CRC
            byte[] tmpBytesCRC = AMBCalculator.InsertCRC(tmpBytes);

            // Escape
            byte[] escapedBytes = AMBCalculator.Escape(tmpBytesCRC);

            // Return
            return escapedBytes;

        }

        public static byte[] Passing(int transponderId, DateTime passingTime)
        {

            DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            TimeSpan epoch = DateTime.Now.Subtract(start);

            Random rand = new Random();

            byte[] transponder = BitConverter.GetBytes(transponderId);

            byte[] time = BitConverter.GetBytes(Convert.ToUInt64(epoch.TotalMilliseconds * 1000));

            byte[] strength = BitConverter.GetBytes(rand.Next(50, 122));
            byte[] hits = BitConverter.GetBytes(rand.Next(7, 30));

            List<byte> bytes = new List<byte>();
            bytes.Add(Convert.ToByte(AMBMessage.SOR));                  // Start Of Record
            bytes.Add(DEFAULT_VERSION);                                 // Version
            bytes.Add(0x00);                                            //
            bytes.Add(0x00);                                            // 
            bytes.Add(0x00);                                            // CRC LSB
            bytes.Add(0x00);                                            // CRC MSB
            bytes.Add(0x00);
            bytes.Add(0x00);
            bytes.Add(Convert.ToByte(AMBMessageType.PASSING));         // Type Of Record
            bytes.Add(0x00);

            /* Field of records */

            //PASSING_NUMBER = 0x01,      // (4 byte) (example of "FOR" - 0x01(TOF):0x04(legth):0x00:0x00:0x00:0x00)
            bytes.Add(Convert.ToByte(AMBPassingFOR.PASSING_NUMBER));
            bytes.Add(0x04);
            bytes.Add(0x00);
            bytes.Add(0x00);
            bytes.Add(0x00);
            bytes.Add(0x00);

            //TRANSPONDER = 0x03,         // (4 bytes)
            bytes.Add(Convert.ToByte(AMBPassingFOR.TRANSPONDER));
            bytes.Add(Convert.ToByte(transponder.Length));
            bytes.AddRange(transponder);


            //RTC_TIME = 0x04,            // (8 byte, time microseconds after January 1, 1970 00:00:00 GMT)
            bytes.Add(Convert.ToByte(AMBPassingFOR.RTC_TIME));
            bytes.Add(Convert.ToByte(time.Length));
            bytes.AddRange(time);

            //STRENGTH = 0x05,            // (2 byte)
            bytes.Add(Convert.ToByte(AMBPassingFOR.STRENGTH));
            bytes.Add(Convert.ToByte(strength.Length));
            bytes.AddRange(strength);

            //HITS = 0x06,                // (2 byte)
            bytes.Add(Convert.ToByte(AMBPassingFOR.HITS));
            bytes.Add(Convert.ToByte(hits.Length));
            bytes.AddRange(hits);

            //FLAGS = 0x08,               // (2 byte)
            bytes.Add(Convert.ToByte(AMBPassingFOR.FLAGS));
            bytes.Add(0x02);
            bytes.Add(0x00);
            bytes.Add(0x00);

            //VOLTAGE = 0x30,             // (1 byte, V = (float)voltage/10)
            bytes.Add(Convert.ToByte(AMBPassingFOR.VOLTAGE));
            bytes.Add(0x01);
            bytes.Add(0x00);

            //RTC_ID = 0x13,              // (4 bytes)
            //UTC_TIME = 0x10,            // (8 byte, time microseconds after January 1, 1970 00:00:00 GMT)
            //TRAN_CODE = 0x0a,           // (1 byte)
            //USER_FLAG = 0x0e,           // (4 byte)
            //DRIVER_ID = 0x0f,           // (1 byte)
            //SPORT = 0x14,               // (1 byte)
            //TEMPERATURE = 0x31

            // End of record
            bytes.Add(Convert.ToByte(AMBMessage.EOR));

            byte[] tmpBytes = bytes.ToArray();

            // Calculate and insert CRC
            byte[] tmpBytesCRC = AMBCalculator.InsertCRC(tmpBytes);

            // Escape
            byte[] escapedBytes = AMBCalculator.Escape(tmpBytesCRC);

            // Return
            return escapedBytes;
        }

        public static byte[] Status(int n, int t, int v)
        {
            byte[] noise = BitConverter.GetBytes(n);
            byte[] temp = BitConverter.GetBytes(t);
            byte[] volt = BitConverter.GetBytes(v);


            List<byte> bytes = new List<byte>();
            bytes.Add(Convert.ToByte(AMBMessage.SOR));                  // Start Of Record
            bytes.Add(DEFAULT_VERSION);                                 // Version
            bytes.Add(0x00);                                            //
            bytes.Add(0x00);                                            // 
            bytes.Add(0x00);                                            // CRC LSB
            bytes.Add(0x00);                                            // CRC MSB
            bytes.Add(0x00);
            bytes.Add(0x00);
            bytes.Add(Convert.ToByte(AMBMessageType.STATUS));           // Type Of Record
            bytes.Add(0x00);

            /* Field of records */

            //NOISE = 0x01,               // (2 byte)
            bytes.Add(Convert.ToByte(AMBStatusFOR.NOISE));
            bytes.Add(Convert.ToByte(noise.Length));
            bytes.AddRange(noise);

            //GPS = 0x06,                 // (1 byte) (0=false, 1 =true)
            bytes.Add(Convert.ToByte(AMBStatusFOR.GPS));
            bytes.Add(0x01);
            bytes.Add(0x00);

            //TEMPERATURE = 0x07,         // (2 byte)
            bytes.Add(Convert.ToByte(AMBStatusFOR.TEMPERATURE));
            bytes.Add(Convert.ToByte(temp.Length));
            bytes.AddRange(temp);

            //INPUT_VOLTAGE = 0x0c,       // (1 byte) (Voltage = (float) input_voltage/10)
            bytes.Add(Convert.ToByte(AMBStatusFOR.INPUT_VOLTAGE));
            bytes.Add(Convert.ToByte(volt.Length));
            bytes.AddRange(volt);

            //SATINUSE = 0x0a,            // (1 byte)
            //LOOP_TRIGGERS = 0x0b,       // (1 byte)

            // End of record
            bytes.Add(Convert.ToByte(AMBMessage.EOR));

            byte[] tmpBytes = bytes.ToArray();

            // Calculate and insert CRC
            byte[] tmpBytesCRC = AMBCalculator.InsertCRC(tmpBytes);

            // Escape
            byte[] escapedBytes = AMBCalculator.Escape(tmpBytesCRC);

            // Return
            return escapedBytes;
        }
    }
}
